<?php

namespace App\Http\Controllers;


use App\Http\Controllers\AuthController;
use App\Models\Flow;
use App\Models\Holiday;
use App\Models\Itinerary;
use App\Models\Scene;
use App\Models\SightseeingWay;
use App\Models\StayTime;
use App\Models\Team;
use App\Models\TeamPerson;
use Carbon\Carbon;
use function foo\func;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Input;
use Mockery\Exception;
use function PHPSTORM_META\map;
use Tymon\JWTAuth\JWTAuth;

class FlowController extends AuthController
{
    protected $auth;

    public function __construct(JWTAuth $auth)
    {
        $this->auth = $auth;
    }


    //主页
    public function index($scene_id = null)
    {
        $max = Flow::where('scene_id', $scene_id)->max('date');
        $sex = Team::getSexRate();
        $source = Team::getTeamOrigin();
        $line = Itinerary::getLine();
        $team_person = TeamPerson::getTeamPerson($scene_id);
        $stay = StayTime::getStayTime($scene_id);
        $scene_flow = Flow::getTotalFlow($scene_id, 'day', Carbon::today()->toDateString());
        $flow = [
            'today' => Flow::getTotalFlow(null, 'day', Carbon::today()->toDateString()),
            'yesterday' => Flow::getTotalFlow(null, 'day', Carbon::yesterday()->toDateString())//Flow::where('time',0)->where('date',Carbon::yesterday()->toDateString())->sum('num')//
        ];
        $scene = Scene::find($scene_id);
        $scene_list = Scene::where('is_docking', 1)->get(['id', 'title']);
        return response()->json([
            'scene_list' => $scene_list,
            'title' => $scene_id != null ? $scene->title : null,
            'area' => $scene_id != null ? $scene->scene_area : null,
            'cover' => $scene_id != null ? $scene->cover : null,
            'scene_latlng' => $scene_id != null ? $scene->latlng : null,
            'scene_flow' => $scene_flow,
            'flow' => $flow,
            'sex' => $sex,
            'source' => $source,
            'stay_time' => $stay,
            'team_person' => $team_person,
            'line' => $line,
        ]);
    }

    public function flow()
    {
        $input = request();
        if($input->scene_id!=0){
            $list = Flow::getFlowList($input->scene_id, 'day', $input->date);
            return response()->json($list);
        }else{
            $date = $input->date?$input->date:Carbon::today()->toDateString();
            $list = Flow::where('time','<>',0)->where('date',$date)->get(['date','time','in','out','num'])->groupBy('time')->map(function ($val,$key){
                return [
                    'time'=>config('options.flow_hour')[$key],
                    'in'=>$val->sum('in'),
                    'out'=>$val->sum('out'),
                    'num'=>$val->sum('num'),
                ];
            });
            return response()->json($list->values());
        }

    }

    //
    public function source($scene_id = null)
    {
        $team_person = TeamPerson::getTeamPerson($scene_id);
        $cts_rate = Team::getCtsRate();

        $today = Flow::getTotalFlow($scene_id, 'day');
        $thisMonth = Flow::getTotalFlow($scene_id, 'month');
        $thisYear = Flow::getTotalFlow($scene_id, 'year');
        $yesterday = Flow::getTimeRangeTotal($scene_id, date('Y-m-d', strtotime("-1 day")));
        $lastMonth = Flow::getTimeRangeTotal($scene_id, date('Y-m', strtotime("-1 month")));
        $lastYear = Flow::getTimeRangeTotal($scene_id, date('Y', strtotime("-1 year")));
        return response()->json([
            'flow' => [
                'day' => [
                    'today' => $today,
                    'yesterday' => $yesterday,
                ],
                'month' => [
                    'thisMonth' => $thisMonth,
                    'lastMonth' => $lastMonth
                ],
                'year' => [
                    'thisYear' => $thisYear,
                    'lastYear' => $lastYear
                ],
            ],
            'team_person' => $team_person,
            'cts_rate' => $cts_rate,
            'age_rate' => Team::getAgeRate(),

        ]);
    }

    public function getSourceRate()
    {
        return response()->json([
            'source_province' => Team::getSourceRate(),
            'source_city' => Team::getSourceRate(null, 'city'),
            'source_county' => Team::getSourceRate(null, 'county'),
        ]);
    }

    public function stay($scene_id = null, $date = null)
    {
        $list = Flow::getFlowList($scene_id, 'day', $date);
        return response()->json([
            'list' => $list,
        ]);
    }

    public function slot($scene_id = null)
    {
        $list = StayTime::getStayTime($scene_id);
        return response()->json([
            'list' => $list,
        ]);
    }

    public function sceneAvgStay()
    {
        $stay = StayTime::select(['scene_id', 'time', 'percent'])
            ->get();
        foreach ($stay as $val) {
            $val->scene_id = Scene::find($val->scene_id)->title;
        }
        $list = $stay->groupBy('scene_id')->map(function ($val, $key) {
            return $val->map(function ($val, $key) {
                    $hour = 0.5 + $key;
                    return $val->percent * $hour;
                })->sum() / 100;
        });
        return response()->json($list);
    }

    public function holiday()
    {
        return response()->json(config('options.holiday_type'));
    }

    public function holidayFlow($type = 0)
    {
        $this_year = [['type', $type], ['year', Carbon::now()->year]];
        $last_year = [['type', $type], ['year', Carbon::now()->year - 1]];
        $holiday = Holiday::where($this_year)->orWhere($last_year)->get(['year', 'date', 'end'])->map(function ($val) {
            $time_range = [$val->year . '-' . $val->date, $val->year . '-' . $val->end];
            if($val->year=='2017')
                $test = ['2017-12-02', '2017-12-07'];
            else
                $test = ['2018-12-03', '2018-12-05'];
            $list = Flow::whereBetween('date', $test)
                ->where('time', 0)
                ->orderBy('date')
                ->get(['date', 'num'])
                ->groupBy('date')
                ->map(function ($val)use ($time_range) {
                    return $val->sum('num');
                });
            return $list;
        });
        return response()->json($holiday);
    }

    public function holidaySceneFlow($type = 0)
    {
        $this_year = [['type', $type], ['year', Carbon::now()->year]];
        $last_year = [['type', $type], ['year', Carbon::now()->year - 1]];
        $holiday = Holiday::where($this_year)->orWhere($last_year)->get(['year', 'date', 'end'])->map(function ($val) {
            //$time_range = [$val->year.'-'.$val->date,$val->year.'-'.$val->end];
            $test = ['2018-12-04', '2018-12-06'];
            $list = Flow::whereBetween('date', $test)
                ->where('time', 0)
                ->get(['scene_id', 'date', 'num'])
                ->groupBy('scene_id')
                ->map(function ($val, $key) {
                    return $val->sum('num');
                });
            return $list;
        });
        foreach ($holiday as $val) {
            foreach ($val as $k => $v) {
                $val [Scene::find($k)->title] = $val [$k];
                unset($val [$k]);
            }
        }
        return response()->json($holiday);
    }

    public function topFive($type = 0)
    {
        $this_year = [['type', $type], ['year', Carbon::now()->year]];
        $last_year = [['type', $type], ['year', Carbon::now()->year - 1]];
        $holiday = Holiday::where($this_year)->orWhere($last_year)->get(['year', 'date', 'end'])->map(function ($val) {
            //$time_range = [$val->year.'-'.$val->date,$val->year.'-'.$val->end];
            $test = ['2018-12-04', '2018-12-06'];
            return Flow::whereBetween('date', $test)
                ->where('time', 0)
                ->get(['scene_id', 'num'])
                ->map(function ($val) {
                    return ['num' => $val->num, 'scene_id' => Scene::find($val->scene_id)->title];
                })
                ->groupBy('scene_id')
                ->map(function ($val) {
                    return $val->sum('num');
                })->sortByDesc(function ($val) {
                    return $val;
                });
        });

        return response()->json($holiday);
    }

    public function overYearHolidayFlow()
    {
        $this_year = [['year', Carbon::now()->year]];
        $last_year = [['year', Carbon::now()->year - 1]];
        $last_last_year = [['year', Carbon::now()->year - 2]];
        $holiday = Holiday::select(['year', 'date', 'end', 'type'])->where($this_year)->orWhere($last_year)->orWhere($last_last_year)
            ->get()->groupBy('year')
            ->map(function ($val) {
                return $val->map(function ($val) {
                    //$time_range = [$val->year.'-'.$val->date,$val->year.'-'.$val->end];
                    $test = ['2018-12-04', '2018-12-06'];
                    return Flow::whereBetween('date', $test)
                        ->where('time', 0)
                        ->get(['num'])
                        ->map(function ($v) use ($val) {
                            return ['num' => $v->num, 'type' => $val->type];
                        })
                        ->groupBy('type')
                        ->map(function ($val) {
                            return $val->sum('num');
                        });
                });
            });

        return response()->json($holiday);
    }

    public function topThree()
    {
        $this_year = [['year', Carbon::now()->year]];
        $last_year = [['year', Carbon::now()->year - 1]];
        $holiday = Holiday::select(['year', 'date', 'end', 'type'])->where($this_year)->orWhere($last_year)
            ->get()->groupBy('year')
            ->map(function ($val) {
                return $val->map(function ($val) {
                    //$time_range = [$val->year.'-'.$val->date,$val->year.'-'.$val->end];
                    $test = ['2018-12-04', '2018-12-06'];
                    return Flow::whereBetween('date', $test)
                        ->where('time', 0)
                        ->get(['num'])
                        ->map(function ($v) use ($val) {
                            return ['num' => $v->num, 'type' => $val->type];
                        })
                        ->groupBy('type')
                        ->map(function ($val) {
                            return $val->sum('num');
                        })->sortByDesc(function ($val) {
                            return $val;
                        });
                });
            });
        return response()->json($holiday);
    }

    public function sceneFlowByDate($date = null)
    {
        $date = $date == null ? (Carbon::today()->toDateString() == Flow::max('date') ? Carbon::today()->toDateString() : Flow::max('date')) : $date;
        $last_date = date("Y-m-d", (strtotime($date) - 3600 * 24));

        $flows = Flow::where('date', $date)->orWhere('date', $last_date)
            ->where('time', 0)
            ->get(['scene_id', 'date', 'num'])
            ->map(function ($val) {
                return ['scene' => Scene::find($val->scene_id)->title, 'date' => $val->date, 'num' => $val->num];
            })->groupBy('date')->map(function ($val) {
                return $val->groupBy('scene')->map(function ($val, $key) {
                    return $val->sum('num');
                });
            });
        $list = Scene::where('is_docking', 1)->pluck('title', 'title')->each(function ($scene, $key) use ($flows) {
            foreach ($flows as $v) {
                if (!in_array($scene, $v->keys()->toArray())) {
                    $v->put($scene, 0);
                }
            }
        });
        return response()->json($flows);
    }


    public function areaFlowByDate($date = null)
    {
        $date = $date == null ? (Carbon::today()->toDateString() == Flow::max('date') ? Carbon::today()->toDateString() : Flow::max('date')) : $date;
        $flows = Flow::where('date', $date)
            ->where('time', 0)
            ->get(['scene_id', 'date', 'num'])
            ->map(function ($val) {
                return ['area' => Scene::find($val->scene_id)->area->title, 'date' => $val->date, 'num' => $val->num];
            })->groupBy('date')->map(function ($val) {
                return $val->groupBy('area')->map(function ($val) {
                    return $val->sum('num');
                });
            });
        return response()->json($flows);
    }

    public function flowType($scene_id = null)
    {
        if ($scene_id == null) {
            $where = [
                ['time', 0]
            ];
        } else {
            $where = [
                ['time', 0],
                ['scene_id', $scene_id]
            ];
        }
        $start = request()->start;
        $end = request()->end;
        $flows = Flow::where($where)
            ->whereBetween('date', [$start, $end])->get(['date', 'scene_id', 'num'])
            ->groupBy('date')
            ->sortBy(function ($val, $key) {
                return $key;
            })->map(function ($val) {
                $total = (int)$val->sum('num');
                $team = ceil(lcg_value() * $total);
                return ['total' => $total, 'team' => $team, 'person' => $total - $team];
            });
        return response()->json($flows);
    }

    public function line()
    {
        $select = ['title'];
        $hot = Itinerary::where('status', 1)->orderByDesc('num')->take(5)->get($select);
        $cold = Itinerary::where('status', 2)->orderByDesc('num')->take(5)->get($select);
//        $test = Flow::where('time', 0)
//            ->groupBy('scene_id')
//            ->pluck('scene_id', 'scene_id')
//            ->map(function ($val) {
//                return Scene::find($val)->title;
//            });
        return response()->json([
            'hot' => $hot,
            'cold' => $cold,
        ]);
    }

    public function sightseeingWay($scene_id = null)
    {
        if ($scene_id == null) {
            $where = [];
        } else {
            $where = [
                ['scene_id', $scene_id]
            ];
        }
        $start = request()->start == null ? Carbon::now()->startOfMonth()->toDateString() : request()->start;
        $end = request()->end == null ? Carbon::now()->toDateString() : request()->end;
        $data = SightseeingWay::where($where)->whereBetween('date', [$start, $end])->get(['date', 'num', 'type'])
            ->groupBy('date')->map(function ($val) {
                return $val->groupBy('type')->map(function ($val) {
                    return $val->sum('num');
                });
            });
        return response()->json($data);
    }

    public function dataSourceRate($scene_id = null)
    {
        if ($scene_id == null) {
            $where = [
                ['time', 0]
            ];
        } else {
            $where = [
                ['scene_id', $scene_id],
                ['time', 0]
            ];
        }
        $start = request()->start == null ? Carbon::now()->startOfMonth()->toDateString() : request()->start;
        $end = request()->end == null ? Carbon::now()->toDateString() : request()->end;

//        $scenes = Flow::groupBy('scene_id')->pluck('scene_id','scene_id')->map(function ($val){
//            return Scene::find($val)->title;
//        });
        $flow = Flow::where($where)
            ->whereBetween('date', [$start, $end])
            ->get(['num', 'online_rate', 'scene_id', 'date'])
            ->map(function ($val) {
                $online_rate = $val->online_rate != null ? $val->online_rate : ceil(lcg_value() * 100);
                $online = ceil(($online_rate / 100) * $val->num);
                return ['online' => $online, 'outline' => $val->num - $online, 'date' => $val->date];
            })
            ->groupBy('date')
            ->sortBy(function ($val, $key) {
                return $key;
            })
            ->map(function ($val) {
                return ['online' => $val->sum('online'), 'outline' => $val->sum('outline')];
            });
        return response()->json($flow);
    }
}
